home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / Apple Game Sprockets / InputSprocket / Sample Drivers / Common Driver Code / ISpPlugInUI.cp < prev    next >
Encoding:
Text File  |  1998-07-14  |  54.5 KB  |  1,974 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************
  2.  
  3. File:      ISpPlugInUI.cp
  4.  
  5. Copyright © 1996, 1997, 1998 Apple Computer, Inc., All Rights Reserved
  6.  
  7.  
  8. You may incorporate this sample code into your applications without
  9. restriction, though the sample code has been provided "AS IS" and the
  10. responsibility for its operation is 100% yours.  However, what you are
  11. not permitted to do is to redistribute the source as "DSC Sample Code"
  12. after having made changes. If you're going to re-distribute the source,
  13. we require that you make it clear in the source that the code was
  14. descended from Apple Sample Code, but that you've made changes.
  15.  
  16. *************************************************************************************/
  17. #ifndef __TEXTUTILS__
  18. #include <TextUtils.h>
  19. #endif
  20.  
  21. #ifndef __RESOURCES__
  22. #include <Resources.h>
  23. #endif
  24.  
  25. #ifndef __SOUND__
  26. #include <Sound.h>
  27. #endif
  28.  
  29. #include "Common.h"
  30. #include "ISpPlugInUI.h"
  31. #include <InputSprocket.h>
  32. #include "InputSprocketDriver.h"
  33. #include "dprintf.h"
  34. #include "DialogUtils.h"
  35.  
  36. #if FORCE_FB
  37. #include "I•Force.h"
  38. #include "InputSprocketForceFeedback.h"
  39. #endif
  40.  
  41. // most of this file is not speed dependet
  42. // we reset near the bottom for the functions
  43. // that might be used during data gathering
  44. #if __MWERKS__
  45. #pragma optimize_for_size on
  46. #endif
  47.  
  48. // valid need kinds for device types
  49. static const UInt16 validMouseKindsCount = 5;
  50. static ISpElementKind validMouseKinds[validMouseKindsCount] = 
  51.                         {         kISpElementKind_Delta,
  52.                                 kISpElementKind_Movement,
  53.                                 kISpElementKind_Axis,
  54.                                 kISpElementKind_DPad,
  55.                                 kISpElementKind_Button};
  56.  
  57. static const UInt16 validDeltaKindsCount = 3;
  58. static ISpElementKind validDeltaKinds[validDeltaKindsCount] = 
  59.                         {         kISpElementKind_Delta,
  60.                                 kISpElementKind_Axis,
  61.                                 kISpElementKind_Button};
  62.  
  63. static const UInt16 validStickKindsCount = 4;
  64. static ISpElementKind validStickKinds[validStickKindsCount] = 
  65.                         {         kISpElementKind_Movement,
  66.                                 kISpElementKind_Axis,
  67.                                 kISpElementKind_DPad,
  68.                                 kISpElementKind_Button};
  69.                                 
  70. static const UInt16 validAxisKindsCount = 2;
  71. static ISpElementKind validAxisKinds[validAxisKindsCount] = 
  72.                         {         kISpElementKind_Axis,
  73.                                 kISpElementKind_Button    };
  74.                                 
  75. static const UInt16 validPOVKindsCount = 4;
  76. static ISpElementKind validPOVKinds[validPOVKindsCount] = 
  77.                         {     kISpElementKind_DPad,
  78.                             kISpElementKind_Movement,
  79.                             kISpElementKind_Axis,
  80.                             kISpElementKind_Button    };
  81.                                 
  82. static const UInt16 validButtonKindsCount = 1;
  83. static ISpElementKind validButtonKinds[validButtonKindsCount] = 
  84.                         {     kISpElementKind_Button    };
  85.  
  86.  
  87.  
  88. // methods
  89.  
  90. ISpPlugInUI::ISpPlugInUI (void)
  91. {
  92.     thumbprint = kThumbprint;
  93. }
  94.  
  95. OSStatus ISpPlugInUI::MHInit(    UInt32 refCon,
  96.                                 UInt32 count, 
  97.                                 ISpNeed needs[], 
  98.                                 ISpElementReference virtualElements[],
  99.                                 Boolean used[],
  100.                                 OSType appCreatorCode,
  101.                                 OSType subCreatorCode, 
  102.                                 UInt32 reserved1,
  103.                                 void* reserved2)
  104. {
  105.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  106.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  107.     
  108.     return plugIn->Init(count,
  109.                         needs,
  110.                         virtualElements,
  111.                         used,
  112.                         appCreatorCode,
  113.                         subCreatorCode,
  114.                         reserved1,
  115.                         reserved2);
  116. }
  117.  
  118. OSStatus ISpPlugInUI::MHStop(UInt32 refCon)
  119. {
  120.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  121.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  122.     
  123.     return plugIn->Stop();
  124. }
  125.  
  126. OSStatus ISpPlugInUI::MHGetSize(UInt32 refCon, Point *minimum, Point *best)
  127. {
  128.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  129.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  130.     
  131.     return plugIn->GetSize(*minimum, *best);
  132. }
  133.  
  134. OSStatus ISpPlugInUI::MHHandleEvent(UInt32 refCon, EventRecord *theEvent, Boolean *handled)
  135. {
  136.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  137.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  138.  
  139.     return plugIn->HandleEvent(*theEvent, *handled);
  140. }
  141.  
  142. OSStatus ISpPlugInUI::MHShow(UInt32 refCon, DialogPtr theDialog, short dialogItemNumber, Rect *r)
  143. {
  144.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  145.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  146.  
  147.     return plugIn->Show(theDialog, dialogItemNumber, *r);
  148. }
  149.  
  150. OSStatus ISpPlugInUI::MHHide(UInt32 refCon)
  151. {
  152.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  153.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  154.  
  155.     return plugIn->Hide();
  156. }
  157.  
  158. OSStatus ISpPlugInUI::MHBeginConfiguration(UInt32 refCon, UInt32 count, ISpNeed needs[])
  159. {
  160.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  161.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  162.  
  163.     return plugIn->BeginConfiguration(count, needs);
  164. }
  165.  
  166. OSStatus ISpPlugInUI::MHEndConfiguration(UInt32 refCon, Boolean accept)
  167. {
  168.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  169.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  170.  
  171.     return plugIn->EndConfiguration(accept);
  172. }
  173.  
  174. OSStatus ISpPlugInUI::MHGetIcon(UInt32 refCon, short *iconSuiteResourceId)
  175. {
  176.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  177.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  178.  
  179.     return plugIn->GetIcon(*iconSuiteResourceId);
  180. }
  181.  
  182. OSStatus ISpPlugInUI::MHGetState(UInt32 refCon, UInt32 buflen, void *buffer, UInt32 *length)
  183. {
  184.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  185.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  186.  
  187.     return plugIn->GetState(buflen, buffer, *length);
  188. }
  189.  
  190. OSStatus ISpPlugInUI::MHSetState(UInt32 refCon, UInt32 length, void *buffer)
  191. {
  192.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  193.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  194.  
  195.     return plugIn->SetState(length, buffer);
  196. }
  197.  
  198. OSStatus ISpPlugInUI::MHDirty(UInt32 refCon, Boolean *dirty)
  199. {
  200.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  201.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  202.  
  203.     return plugIn->Dirty(*dirty);
  204. }
  205.  
  206. OSStatus ISpPlugInUI::MHSetActive(UInt32 refCon, Boolean active)
  207. {
  208.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  209.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  210.  
  211.     return plugIn->SetActive(active);
  212. }
  213.  
  214. OSStatus ISpPlugInUI::MHDialogItemHit(UInt32 refCon, short itemHit)
  215. {
  216.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  217.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  218.  
  219.     return plugIn->DialogItemHit(itemHit);
  220. }
  221.  
  222. OSStatus ISpPlugInUI::MHTickle(UInt32 refCon)
  223. {
  224.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  225.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  226.  
  227.     return plugIn->Tickle();
  228. }
  229.  
  230. OSStatus ISpPlugInUI::MHInterruptTickle(UInt32 refCon)
  231. {
  232.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  233.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  234.  
  235.     return plugIn->InterruptTickle();
  236. }
  237.  
  238. OSStatus ISpPlugInUI::MHDraw(UInt32 refCon)
  239. {
  240.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  241.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  242.  
  243.     return plugIn->Draw();
  244. }
  245.  
  246.  
  247. OSStatus ISpPlugInUI::MHClick(UInt32 refCon, const EventRecord *event)
  248. {
  249.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  250.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  251.  
  252.     return plugIn->Click(*event);
  253. }
  254.  
  255. OSStatus ISpPlugInUI::MHADBReInit(UInt32 refCon, Boolean inPostProcess)
  256. {
  257.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  258.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  259.  
  260.     return plugIn->ADBReInit(inPostProcess);
  261. }
  262.  
  263. #if FORCE_FB
  264.  
  265. OSStatus ISpPlugInUI::MHBuffeting(UInt32 refCon, UInt32 inMagnitude)
  266. {
  267.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  268.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  269.  
  270.     OSStatus status = noErr;
  271.     if (!IF_Buffeting (inMagnitude))
  272.         status = -1;
  273.     
  274.     return status;
  275. }
  276.  
  277. OSStatus ISpPlugInUI::MHBuffetingClear(UInt32 refCon)
  278. {
  279.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  280.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  281.  
  282.     OSStatus status = noErr;
  283.     if(!IF_BuffetingClear ())
  284.         status = -1;
  285.     
  286.     return status;
  287. }
  288.  
  289. OSStatus ISpPlugInUI::MHButtonReflexJolt(UInt32 refCon, UInt32 inButton, UInt32 inMagnitude, SInt32 inDirection, UInt32 inDuration, UInt32 inRepeatRate)
  290. {
  291.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  292.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  293.  
  294.     OSStatus status = noErr;
  295.     if(!IF_ButtonReflexJolt (inButton, inMagnitude, inDirection, inDuration, inRepeatRate))
  296.         status = -1;
  297.     
  298.     return status;
  299. }
  300.  
  301. OSStatus ISpPlugInUI::MHButtonReflexClear(UInt32 refCon, UInt32 inButton)
  302. {
  303.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  304.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  305.  
  306.     OSStatus status = noErr;
  307.     if(!IF_ButtonReflexClear (inButton))
  308.         status = -1;
  309.     
  310.     return status;
  311. }
  312.  
  313. OSStatus ISpPlugInUI::MHJolt(UInt32 refCon, UInt32 inMagnitude, SInt32 inDirection, UInt32 inDuration)
  314. {
  315.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  316.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  317.  
  318.     OSStatus status = noErr;
  319.     if(!IF_Jolt (inMagnitude, inDirection, inDuration))
  320.         status = -1;
  321.     
  322.     return status;
  323. }
  324.  
  325. OSStatus ISpPlugInUI::MHXVibration(UInt32 refCon, UInt32 inLeftMagnitude, UInt32 inRightMagnitude, UInt32 inFrequency)
  326. {
  327.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  328.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  329.  
  330.     OSStatus status = noErr;
  331.     if(!IF_XVibration (inLeftMagnitude, inRightMagnitude, inFrequency))
  332.         status = -1;
  333.     
  334.     return status;
  335. }
  336.  
  337. OSStatus ISpPlugInUI::MHXVibrationClear(UInt32 refCon)
  338. {
  339.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  340.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  341.  
  342.     OSStatus status = noErr;
  343.     if(!IF_XVibrationClear ())
  344.         status = -1;
  345.     
  346.     return status;
  347. }
  348.  
  349. OSStatus ISpPlugInUI::MHYVibration(UInt32 refCon, UInt32 inUpMagnitude, UInt32 inDownMagnitude, UInt32 inFrequency)
  350. {
  351.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  352.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  353.  
  354.     OSStatus status = noErr;
  355.     if(!IF_YVibration (inUpMagnitude, inDownMagnitude, inFrequency))
  356.         status = -1;
  357.     
  358.     return status;
  359. }
  360.  
  361. OSStatus ISpPlugInUI::MHYVibrationClear(UInt32 refCon)
  362. {
  363.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  364.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  365.  
  366.     OSStatus status = noErr;
  367.     if(!IF_YVibrationClear ())
  368.         status = -1;
  369.     
  370.     return status;
  371. }
  372.  
  373. OSStatus ISpPlugInUI::MHVectorForce(UInt32 refCon, UInt32 inMagnitude, SInt32 inDirection)
  374. {
  375.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  376.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  377.  
  378.     OSStatus status = noErr;
  379.     if(!IF_VectorForce (inMagnitude, inDirection))
  380.         status = -1;
  381.     
  382.     return status;
  383. }
  384.  
  385. OSStatus ISpPlugInUI::MHVectorForceClear(UInt32 refCon)
  386. {
  387.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  388.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  389.  
  390.     OSStatus status = noErr;
  391.     if(!IF_VectorForceClear ())
  392.         status = -1;
  393.     
  394.     return status;
  395. }
  396.  
  397. OSStatus ISpPlugInUI::MHXYVectorForce(UInt32 refCon, SInt32 inXMagnitude, SInt32 inYMagnitude)
  398. {
  399.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  400.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  401.  
  402.     OSStatus status = noErr;
  403.     if(!IF_XYVectorForce (inXMagnitude, inYMagnitude))
  404.         status = -1;
  405.     
  406.     return status;
  407. }
  408.  
  409. OSStatus ISpPlugInUI::MHXSpring(UInt32 refCon, SInt32 inOrigin, UInt32 inLeftStiffness, UInt32 inRightStiffness)
  410. {
  411.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  412.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  413.  
  414.     OSStatus status = noErr;
  415.     if(!IF_XSpring (inOrigin, inLeftStiffness, inRightStiffness))
  416.         status = -1;
  417.     
  418.     return status;
  419. }
  420.  
  421. OSStatus ISpPlugInUI::MHXSpringClear(UInt32 refCon)
  422. {
  423.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  424.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  425.  
  426.     OSStatus status = noErr;
  427.     if(!IF_XSpringClear ())
  428.         status = -1;
  429.     
  430.     return status;
  431. }
  432.  
  433. OSStatus ISpPlugInUI::MHYSpring(UInt32 refCon, SInt32 inOrigin, UInt32 inUpStiffness, UInt32 inDownStiffness)
  434. {
  435.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  436.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  437.  
  438.     OSStatus status = noErr;
  439.     if(!IF_YSpring (inOrigin, inUpStiffness, inDownStiffness))
  440.         status = -1;
  441.     
  442.     return status;
  443. }
  444.  
  445. OSStatus ISpPlugInUI::MHYSpringClear(UInt32 refCon)
  446. {
  447.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  448.     CHECK(plugIn->thumbprint == kThumbprint, paramErr);
  449.  
  450.     OSStatus status = noErr;
  451.     if(!IF_YSpringClear ())
  452.         status = -1;
  453.     
  454.     return status;
  455. }
  456.  
  457. #endif    /* FORCE_FB */
  458.  
  459. ISpDriverFunctionPtr_Generic ISpPlugInUI::MetaHandler(UInt32 refCon, ISpMetaHandlerSelector selector)
  460. {
  461.     ISpDriverFunctionPtr_Generic function = NULL;
  462.     
  463.     ISpPlugInUI *plugIn = (ISpPlugInUI *) refCon;
  464.     CHECK(plugIn->thumbprint == kThumbprint, NULL);
  465.     
  466.     switch(selector)
  467.     {
  468.         case kISpSelector_Init:
  469.             ISpDriverFunctionPtr_Init funcInit = (ISpDriverFunctionPtr_Init) ISpPlugInUI::MHInit;
  470.             function = (ISpDriverFunctionPtr_Generic) funcInit;
  471.         break;
  472.         
  473.         case kISpSelector_Stop:
  474.             ISpDriverFunctionPtr_Stop funcStop = (ISpDriverFunctionPtr_Stop) ISpPlugInUI::MHStop;
  475.             function = (ISpDriverFunctionPtr_Generic) funcStop;
  476.         break;
  477.         
  478.         case kISpSelector_GetSize:
  479.             ISpDriverFunctionPtr_GetSize funcGetSize = (ISpDriverFunctionPtr_GetSize) ISpPlugInUI::MHGetSize;
  480.             function = (ISpDriverFunctionPtr_Generic) funcGetSize;
  481.         break;
  482.         
  483.         case kISpSelector_HandleEvent:
  484.             ISpDriverFunctionPtr_HandleEvent funcHandleEvent = (ISpDriverFunctionPtr_HandleEvent) ISpPlugInUI::MHHandleEvent;
  485.             function = (ISpDriverFunctionPtr_Generic) funcHandleEvent;
  486.         break;
  487.         
  488.         case kISpSelector_Show:
  489.             ISpDriverFunctionPtr_Show funcShow = (ISpDriverFunctionPtr_Show) ISpPlugInUI::MHShow;
  490.             function = (ISpDriverFunctionPtr_Generic) funcShow;
  491.         break;
  492.         
  493.         case kISpSelector_Hide:
  494.             ISpDriverFunctionPtr_Hide funcHide = (ISpDriverFunctionPtr_Hide) ISpPlugInUI::MHHide;
  495.             function = (ISpDriverFunctionPtr_Generic) funcHide;
  496.         break;
  497.         
  498.         case kISpSelector_BeginConfiguration:
  499.             ISpDriverFunctionPtr_BeginConfiguration funcBeginConfiguration = (ISpDriverFunctionPtr_BeginConfiguration) ISpPlugInUI::MHBeginConfiguration;
  500.             function = (ISpDriverFunctionPtr_Generic) funcBeginConfiguration;
  501.         break;
  502.         
  503.         case kISpSelector_EndConfiguration:
  504.             ISpDriverFunctionPtr_EndConfiguration funcEndConfiguration = (ISpDriverFunctionPtr_EndConfiguration) ISpPlugInUI::MHEndConfiguration;
  505.             function = (ISpDriverFunctionPtr_Generic) funcEndConfiguration;
  506.         break;
  507.         
  508.         case kISpSelector_GetIcon:
  509.             ISpDriverFunctionPtr_GetIcon funcGetIcon = (ISpDriverFunctionPtr_GetIcon) ISpPlugInUI::MHGetIcon;
  510.             function = (ISpDriverFunctionPtr_Generic) funcGetIcon;
  511.         break;
  512.         
  513.         case kISpSelector_GetState:
  514.             ISpDriverFunctionPtr_GetState funcGetState = (ISpDriverFunctionPtr_GetState) ISpPlugInUI::MHGetState;
  515.             function = (ISpDriverFunctionPtr_Generic) funcGetState;
  516.         break;
  517.         
  518.         case kISpSelector_SetState:
  519.             ISpDriverFunctionPtr_SetState funcSetState = (ISpDriverFunctionPtr_SetState) ISpPlugInUI::MHSetState;
  520.             function = (ISpDriverFunctionPtr_Generic) funcSetState;
  521.         break;
  522.         
  523.         case kISpSelector_Dirty:
  524.             ISpDriverFunctionPtr_Dirty funcDirty = (ISpDriverFunctionPtr_Dirty) ISpPlugInUI::MHDirty;
  525.             function = (ISpDriverFunctionPtr_Generic) funcDirty;
  526.         break;
  527.         
  528.         case kISpSelector_SetActive:
  529.             ISpDriverFunctionPtr_SetActive funcSetActive = (ISpDriverFunctionPtr_SetActive) ISpPlugInUI::MHSetActive;
  530.             function = (ISpDriverFunctionPtr_Generic) funcSetActive;
  531.         break;
  532.         
  533.         case kISpSelector_DialogItemHit:
  534.             ISpDriverFunctionPtr_DialogItemHit funcDialogItemHit = (ISpDriverFunctionPtr_DialogItemHit) ISpPlugInUI::MHDialogItemHit;
  535.             function = (ISpDriverFunctionPtr_Generic) funcDialogItemHit;
  536.         break;
  537.         
  538.         case kISpSelector_Tickle:
  539.             ISpDriverFunctionPtr_Tickle funcTickle = (ISpDriverFunctionPtr_Tickle) ISpPlugInUI::MHTickle;
  540.             function = (ISpDriverFunctionPtr_Generic) funcTickle;
  541.         break;
  542.         
  543.         case kISpSelector_InterruptTickle:
  544.             ISpDriverFunctionPtr_InterruptTickle funcInterruptTickle = (ISpDriverFunctionPtr_InterruptTickle) ISpPlugInUI::MHInterruptTickle;
  545.             function = (ISpDriverFunctionPtr_Generic) funcInterruptTickle;
  546.         break;
  547.         
  548.         case kISpSelector_Draw:
  549.             ISpDriverFunctionPtr_Draw funcDraw = (ISpDriverFunctionPtr_Draw) ISpPlugInUI::MHDraw;
  550.             function = (ISpDriverFunctionPtr_Generic) funcDraw;
  551.         break;
  552.         
  553.         case kISpSelector_Click:
  554.             ISpDriverFunctionPtr_Click funcClick = (ISpDriverFunctionPtr_Click) ISpPlugInUI::MHClick;
  555.             function = (ISpDriverFunctionPtr_Generic) funcClick;
  556.         break;
  557.         
  558.         case kISpSelector_ADBReInit:
  559.             ISpDriverFunctionPtr_ADBReInit funcADBReInit = (ISpDriverFunctionPtr_ADBReInit) ISpPlugInUI::MHADBReInit;
  560.             function = (ISpDriverFunctionPtr_Generic) funcADBReInit;
  561.         break;
  562.     
  563. #if FORCE_FB
  564.         case kISpSelector_Buffeting:
  565.             ISpDriverFunctionPtr_Buffeting funcBuffeting = ISpPlugInUI::MHBuffeting;
  566.             function = (ISpDriverFunctionPtr_Generic) funcBuffeting;
  567.         break;
  568.  
  569.         case kISpSelector_BuffetingClear:
  570.             ISpDriverFunctionPtr_BuffetingClear funcBuffetingClear = ISpPlugInUI::MHBuffetingClear;
  571.             function = (ISpDriverFunctionPtr_Generic) funcBuffetingClear;
  572.         break;
  573.  
  574.         case kISpSelector_ButtonReflexJolt:
  575.             ISpDriverFunctionPtr_ButtonReflexJolt funcButtonReflexJolt = ISpPlugInUI::MHButtonReflexJolt;
  576.             function = (ISpDriverFunctionPtr_Generic) funcButtonReflexJolt;
  577.         break;
  578.  
  579.         case kISpSelector_ButtonReflexClear:
  580.             ISpDriverFunctionPtr_ButtonReflexClear funcButtonReflexClear = ISpPlugInUI::MHButtonReflexClear;
  581.             function = (ISpDriverFunctionPtr_Generic) funcButtonReflexClear;
  582.         break;
  583.  
  584.         case kISpSelector_Jolt:
  585.             ISpDriverFunctionPtr_Jolt funcJolt = ISpPlugInUI::MHJolt;
  586.             function = (ISpDriverFunctionPtr_Generic) funcJolt;
  587.         break;
  588.  
  589.         case kISpSelector_XVibration:
  590.             ISpDriverFunctionPtr_XVibration funcXVibration = ISpPlugInUI::MHXVibration;
  591.             function = (ISpDriverFunctionPtr_Generic) funcXVibration;
  592.         break;
  593.  
  594.         case kISpSelector_XVibrationClear:
  595.             ISpDriverFunctionPtr_XVibrationClear funcXVibrationClear = ISpPlugInUI::MHXVibrationClear;
  596.             function = (ISpDriverFunctionPtr_Generic) funcXVibrationClear;
  597.         break;
  598.  
  599.         case kISpSelector_YVibration:
  600.             ISpDriverFunctionPtr_YVibration funcYVibration = ISpPlugInUI::MHYVibration;
  601.             function = (ISpDriverFunctionPtr_Generic) funcYVibration;
  602.         break;
  603.  
  604.         case kISpSelector_YVibrationClear:
  605.             ISpDriverFunctionPtr_YVibrationClear funcYVibrationClear = ISpPlugInUI::MHYVibrationClear;
  606.             function = (ISpDriverFunctionPtr_Generic) funcYVibrationClear;
  607.         break;
  608.  
  609.         case kISpSelector_VectorForce:
  610.             ISpDriverFunctionPtr_VectorForce funcVectorForce = ISpPlugInUI::MHVectorForce;
  611.             function = (ISpDriverFunctionPtr_Generic) funcVectorForce;
  612.         break;
  613.  
  614.         case kISpSelector_VectorForceClear:
  615.             ISpDriverFunctionPtr_VectorForceClear funcVectorForceClear = ISpPlugInUI::MHVectorForceClear;
  616.             function = (ISpDriverFunctionPtr_Generic) funcVectorForceClear;
  617.         break;
  618.  
  619.         case kISpSelector_XYVectorForce:
  620.             ISpDriverFunctionPtr_XYVectorForce funkXYVectorForce = ISpPlugInUI::MHXYVectorForce;
  621.             function = (ISpDriverFunctionPtr_Generic) funkXYVectorForce;
  622.         break;
  623.  
  624.         case kISpSelector_XSpring:
  625.             ISpDriverFunctionPtr_XSpring funkXSpring = ISpPlugInUI::MHXSpring;
  626.             function = (ISpDriverFunctionPtr_Generic) funkXSpring;
  627.         break;
  628.  
  629.         case kISpSelector_XSpringClear:
  630.             ISpDriverFunctionPtr_XSpringClear funkXSpringClear = ISpPlugInUI::MHXSpringClear;
  631.             function = (ISpDriverFunctionPtr_Generic) funkXSpringClear;
  632.         break;
  633.  
  634.         case kISpSelector_YSpring:
  635.             ISpDriverFunctionPtr_YSpring funkYSpring = ISpPlugInUI::MHYSpring;
  636.             function = (ISpDriverFunctionPtr_Generic) funkYSpring;
  637.         break;
  638.  
  639.         case kISpSelector_YSpringClear:
  640.             ISpDriverFunctionPtr_YSpringClear funkYSpringClear = ISpPlugInUI::MHYSpringClear;
  641.             function = (ISpDriverFunctionPtr_Generic) funkYSpringClear;
  642.         break;
  643.  
  644. #endif    /* FORCE_FB */
  645.  
  646.     }
  647.  
  648.     return function;
  649. }
  650.  
  651. OSStatus ISpPlugInUI::Dirty(Boolean &dirty)
  652. {
  653.     dirty = mDirty;
  654.     mDirty = false;
  655.     
  656.     return noErr;
  657. }
  658.  
  659. /* =============================================================================
  660.  *        SetDialogControl (private)
  661.  *
  662.  *    CHanges the value of the control whose dialog item number is inItem in the
  663.  *    original DITL.
  664.  * ========================================================================== */
  665. void ISpPlugInUI::SetDialogControl(
  666.     short                inRelDialogItem,
  667.     short                inValue)
  668. {
  669.     short itemType;
  670.     Handle itemHandle;
  671.     Rect itemBounds;
  672.     short item = inRelDialogItem+mBaseDITLCount;
  673.  
  674.     WARNING(mDialog != nil,                "ISpPlugInUI::SetDialogControl mDialog == nil");
  675.     WARNING(item <= CountDITL(mDialog),    "ISpPlugInUI::SetDialogControl inRelDialogItem to large");
  676.     WARNING(inRelDialogItem > 0,        "ISpPlugInUI::SetDialogControl inRelDialogItem <= 0");
  677.     
  678.     GetDialogItem(mDialog, item, &itemType, &itemHandle, &itemBounds);
  679.     WARNING(itemHandle != nil,            "ISpPlugInUI::SetDialogControl Handle == nil");
  680.     WARNING(itemType & ctrlItem,         "ISpPlugInUI::SetDialogControl: (itemType & ctrlItem) == 0");
  681.     
  682.     if ((itemType & ctrlItem) && itemHandle != nil)
  683.         SetControlValue((ControlHandle) itemHandle, inValue);
  684. }
  685.  
  686. ISpPlugInUI::DirectionType ISpPlugInUI::GetDirection2D(ISpElementLabel label)
  687. {
  688.     DirectionType direction;
  689.     DirectionType direction2D;
  690.     
  691.     direction = GetDirection(label);
  692.     
  693.     switch(direction)
  694.     {
  695.         case kDirection_X:
  696.         case kDirection_Roll:
  697.         case kDirection_Yaw:
  698.             direction2D = kDirection_X;
  699.             break;
  700.             
  701.         case kDirection_Y:
  702.         case kDirection_Z:
  703.         case kDirection_Pitch:
  704.             direction2D = kDirection_Y;
  705.             break;
  706.             
  707.         case kDirection_None:
  708.         default:
  709.             direction2D = kDirection_None;
  710.     }
  711.     
  712.     return direction2D;
  713. }
  714.  
  715. ISpPlugInUI::DirectionType ISpPlugInUI::GetDirection(ISpElementLabel label)
  716. {
  717.     DirectionType    direction;
  718.     
  719.     switch(label)
  720.     {        
  721.         case kISpElementLabel_Axis_XAxis:
  722.         case kISpElementLabel_Delta_X:
  723.         case kISpElementLabel_Btn_SlideLeft:
  724.         case kISpElementLabel_Btn_SlideRight:
  725.             direction = kDirection_X;
  726.             break;
  727.  
  728.         case kISpElementLabel_Axis_YAxis:
  729.         case kISpElementLabel_Delta_Y:
  730.             direction = kDirection_Y;
  731.             break;
  732.  
  733.         case kISpElementLabel_Axis_ZAxis:
  734.         case kISpElementLabel_Axis_Gas:
  735.         case kISpElementLabel_Delta_Z:
  736.         case kISpElementLabel_Axis_Throttle:
  737.         case kISpElementLabel_Btn_MoveForward:
  738.         case kISpElementLabel_Btn_MoveBackward:
  739.             direction = kDirection_Z;
  740.             break;
  741.  
  742.         case kISpElementLabel_Axis_Rx:
  743.         case kISpElementLabel_Axis_PitchTrim:
  744.         case kISpElementLabel_Delta_Rx:
  745.         case kISpElementLabel_Btn_LookUp:
  746.         case kISpElementLabel_Btn_LookDown:
  747.             direction = kDirection_Rx;
  748.             break;
  749.  
  750.         case kISpElementLabel_Axis_Ry:
  751.         case kISpElementLabel_Axis_YawTrim:
  752.         case kISpElementLabel_Delta_Ry:
  753.             direction = kDirection_Ry;
  754.             break;
  755.  
  756.         case kISpElementLabel_Axis_Rz:    
  757.         case kISpElementLabel_Axis_RollTrim:
  758.         case kISpElementLabel_Delta_Rz:
  759.         case kISpElementLabel_Axis_Rudder:
  760.         case kISpElementLabel_Btn_TurnLeft:
  761.         case kISpElementLabel_Btn_TurnRight:
  762.         case kISpElementLabel_Btn_LookLeft:
  763.         case kISpElementLabel_Btn_LookRight:
  764.             direction = kDirection_Rz;
  765.             break;
  766.             
  767.         case kISpElementLabel_None:
  768.         case kISpElementLabel_Axis_Brake:
  769.         case kISpElementLabel_Axis_Clutch:
  770.         case kISpElementLabel_Pad_POV:
  771.         case kISpElementLabel_Pad_Move:
  772.         case kISpElementLabel_Pad_POV_Horiz:
  773.         case kISpElementLabel_Pad_Move_Horiz:
  774.         case kISpElementLabel_Btn_Fire:
  775.         case kISpElementLabel_Btn_SecondaryFire:
  776.         case kISpElementLabel_Btn_Jump:
  777.         case kISpElementLabel_Btn_PauseResume:
  778.         case kISpElementLabel_Btn_Select:
  779.         case kISpElementLabel_Btn_Next:
  780.         case kISpElementLabel_Btn_Previous:
  781.         case kISpElementLabel_Btn_SideStep:
  782.         case kISpElementLabel_Btn_Run:
  783.         case kISpElementLabel_Btn_Look:
  784.         default:
  785.             direction = kDirection_None;
  786.     }
  787.     
  788.     return direction;
  789. }
  790.  
  791. Boolean ISpPlugInUI::IsAppropriateNeedForButton(
  792.         ISpNeed &        need,
  793.         ISpElementLabel    buttonLabel)
  794. {
  795.     buttonLabel;
  796.     
  797.     if ((need.theKind == kISpElementKind_Axis) && (need.flags & kISpNeedFlag_Axis_AlreadyButton)) 
  798.         { return false; }
  799.  
  800.     if ((need.theKind == kISpElementKind_Delta) && (need.flags & kISpNeedFlag_Delta_AlreadyButton)) 
  801.         { return false; }
  802.         
  803.     return true;
  804. }
  805.  
  806. Boolean ISpPlugInUI::IsAppropriateNeedForDPad(
  807.         ISpNeed &        need,
  808.         ISpElementLabel    dpadLabel)
  809. {
  810.     dpadLabel;
  811.     
  812.     if ((need.theKind == kISpElementKind_Axis) && (need.flags & kISpNeedFlag_Axis_AlreadyButton)) 
  813.         { return false; }
  814.  
  815.     if ((need.theKind == kISpElementKind_Delta) && (need.flags & kISpNeedFlag_Delta_AlreadyButton)) 
  816.         { return false; }
  817.  
  818.     return true;
  819. }
  820.  
  821. Boolean ISpPlugInUI::IsAppropriateNeedForAxis(
  822.         ISpNeed &        need,
  823.         ISpElementLabel    axisLabel)
  824. {
  825.     axisLabel;
  826.     
  827.     if ((need.theKind == kISpElementKind_Button) && (need.flags & kISpNeedFlag_Button_AlreadyAxis)) 
  828.         { return false; }
  829.  
  830.     if ((need.theKind == kISpElementKind_Delta) && (need.flags & kISpNeedFlag_Delta_AlreadyAxis)) 
  831.         { return false; }
  832.  
  833.     return true;
  834. }
  835.  
  836. Boolean ISpPlugInUI::IsAppropriateNeedForDelta(
  837.         ISpNeed &        need,
  838.         ISpElementLabel    deltaLabel)
  839. {
  840.     deltaLabel;
  841.     
  842.     if ((need.theKind == kISpElementKind_Button) && (need.flags & kISpNeedFlag_Button_AlreadyDelta)) 
  843.         { return false; }
  844.  
  845.     if ((need.theKind == kISpElementKind_Button) && (need.flags & kISpNeedFlag_Button_AlreadyAxis)) 
  846.         { return false; }
  847.  
  848.     if ((need.theKind == kISpElementKind_Axis) && (need.flags & kISpNeedFlag_Axis_AlreadyDelta)) 
  849.         { return false; }
  850.  
  851.     return true;
  852. }
  853.  
  854.  
  855. /* =============================================================================
  856.  *        IsAppropriateNeed (private)
  857.  *
  858.  *    Returns true if the indexed need is 'appropriate' for the specified element label.
  859.  * ========================================================================== */
  860. Boolean ISpPlugInUI::IsAppropriateNeed(
  861.     ISpNeed &        need,
  862.     ISpElementKind    elementKind,
  863.     ISpElementLabel elementLabel)
  864. {
  865.     Boolean isAppropriate = true;
  866.  
  867.     // step 1 do direction service (return on failure)
  868.     DirectionType needDirection        = GetDirection2D(need.theLabel);
  869.     DirectionType deviceDirection    = GetDirection2D(elementLabel);
  870.     
  871.     if ((needDirection != kDirection_None) && (deviceDirection != kDirection_None))
  872.     {
  873.         if (needDirection != deviceDirection) { return false; }
  874.     }
  875.     
  876.     // step 2 do datatype specific service
  877.     switch(elementKind)
  878.     {
  879.         case kISpElementKind_Button:    // physical device = button
  880.             isAppropriate = IsAppropriateNeedForButton(need, elementLabel);
  881.             break;
  882.         case kISpElementKind_Axis:        // physical device = axis
  883.             isAppropriate = IsAppropriateNeedForAxis(need, elementLabel);
  884.             break;
  885.         case kISpElementKind_Delta:        // physical device = delta
  886.             isAppropriate = IsAppropriateNeedForDelta(need, elementLabel);
  887.             break;
  888.         case kISpElementKind_DPad:        // physical device = dpad
  889.             isAppropriate = IsAppropriateNeedForDPad(need, elementLabel);
  890.             break;
  891.     }
  892.     
  893.     return isAppropriate;
  894. }
  895.  
  896. /* =============================================================================
  897.  *        CheckPopUpHit (protected)
  898.  *
  899.  * inputs:
  900.  * inWhere    - local coordinates of where the user clicked
  901.  * inDialogItem - the dialog item you are checking to see if it was clicked
  902.  * validKinds - an array of kinds that you want to be in the popup
  903.  * numKinds - the size of the valid kinds array
  904.  * inNeed - currently selected need
  905.  *
  906.  * ouputs:
  907.  * clicked - true if a new item was selected, false otherwise
  908.  * outNeed - if returning true then this is the newly selected need
  909.  * ========================================================================== */
  910. Boolean ISpPlugInUI::CheckPopUpHit(
  911.     Point                inWhere,
  912.     short                inDialogItem,
  913.     ISpElementKind        elementKind,
  914.     ISpElementLabel     elementLabel,
  915.     ISpElementKind        *validKinds,
  916.     UInt32                numKinds,
  917.     UInt32                inNeed,
  918.     UInt32                &outNeed)
  919. {
  920. #if DEBUG
  921.     GrafPtr debug_graf_ptr; GetPort(&debug_graf_ptr);
  922. #endif
  923.  
  924.     WARNING(CountDITL(mDialog) >=  inDialogItem,                 "ISpPlugInUI::CheckPopUpHit inDialogItem out of range");
  925.     WARNING(debug_graf_ptr == mDialog,                            "ISpPlugInUI::CheckPopUpHit wrong port was set");
  926.     WARNING((inNeed < mNumNeeds) || (inNeed == kUnsetIndex),     "ISpPlugInUI::CheckPopUpHit inNeed out of range");
  927.     WARNING(numKinds != 0,                                        "ISpPlugInUI::CheckPopUpHit numKinds was zero");
  928.     WARNING(validKinds != nil,                                    "ISpPlugInUI::CheckPopUpHit validKinds was nil");
  929.     // NOTE: add assert to make sure the temp menu does not already exist
  930.     
  931.     OSStatus status = noErr;
  932.     
  933.     // whether an item was selected in popup
  934.     Boolean result = false;
  935.  
  936.  
  937.     // invisable ?                
  938.     if (DialogItemIsInvisable (mDialog, inDialogItem))        // if item is hidden, return false
  939.         { return false; }
  940.  
  941.     // did we miss the popup ?
  942.     Rect itemBounds;    
  943.     DialogItem_GetRect(mDialog, inDialogItem, &itemBounds);
  944.  
  945.     if (!PtInRect(inWhere, &itemBounds))
  946.         { return false; }
  947.     
  948.     // do the actual work
  949.     short inMenuItem = 0;
  950.  
  951.     // preflight for memory
  952.     WARNING(::FreeMem() >= 4096, "ISpPlugInUI::CheckPopUpHit low on memory");
  953.     if (::FreeMem() < 4096) { SysBeep(12); return false; }
  954.     
  955.     // get the modifiers
  956.     EventModifiers    keyModifiers        = GetKeyModifiers();
  957.  
  958.     // 1. build the menu
  959.     MenuHandle theMenu = NewMenu(kMenuID_TempMenu, "\p");
  960.     WARNING(theMenu != nil, "ISpPlugInUI: NewMenu built a nil menu");
  961.     
  962.     UInt32 menuItemCount = 0;
  963.     
  964.     UInt32 kindIndex = 0;
  965.     UInt32 needIndex;
  966.     
  967.     UInt32    firstKindFound = kUnsetIndex;
  968.     for (kindIndex = 0; kindIndex < numKinds; kindIndex++)
  969.     {            
  970.         Boolean    seperatorAdded = false;
  971.     
  972.         for(needIndex = 0; needIndex < mNumNeeds; needIndex++)
  973.         {
  974.             if (mNeeds[needIndex].theKind == validKinds[kindIndex] &&
  975.                 // only show appropriate labels unless option key is down (unless it was already selected)
  976.                 (needIndex == inNeed || (keyModifiers & optionKey) || IsAppropriateNeed (mNeeds[needIndex], elementKind, elementLabel)) &&
  977.                 // don't show needs with kISpNeedFlag_Utility bit set unless the option key is down (unless it was already selected)
  978.                 (needIndex == inNeed || (keyModifiers & optionKey) || !(mNeeds[needIndex].flags & kISpNeedFlag_Utility)))
  979.             {
  980.                 if (!seperatorAdded)
  981.                 {
  982.                     if (firstKindFound == kUnsetIndex) { firstKindFound = kindIndex; }
  983.                     else if (firstKindFound != kindIndex)
  984.                     {
  985.                         AppendMenu(theMenu, "\p(-");  // for balance)
  986.                         menuItemCount++;
  987.  
  988.                         seperatorAdded = true;
  989.                     }
  990.                 }    
  991.                 
  992.                 menuItemCount++;
  993.                 
  994.                 AppendMenu(theMenu, "\pXXX"); // no meta characters
  995.                 SetMenuItemText(theMenu, menuItemCount, mNeeds[needIndex].name);
  996.                 
  997.                 WARNING(mNeeds[needIndex].name[0] != 0, "ISpPlugInUI::CheckPopUpHit appended a 0 length string");
  998.                 
  999.                 // 2. find the current item
  1000.                 if (needIndex == inNeed)
  1001.                 {
  1002.                     inMenuItem = menuItemCount;
  1003.                 }
  1004.             }
  1005.         }
  1006.     }
  1007.  
  1008.     
  1009.     // 2. add an item that contains nothing
  1010.     AppendMenu(theMenu, "\p(-");  // for balance)
  1011.     menuItemCount++;
  1012.     
  1013.     // 2.1 get the none string
  1014.     Str255 nothingString;
  1015.     GetIndString(nothingString, kStrList_PlugInUI, kStrList_PlugInUI_None);
  1016.     WARNING(nothingString[0] != 0, "CheckPopupHit failed to get none string");
  1017.  
  1018.     // 2.2 add it to the menu
  1019.     AppendMenu(theMenu, nothingString);
  1020.     menuItemCount++;
  1021.  
  1022.     // 2.5 check the seleceted item in the menu, or check the none item    
  1023.     if (inMenuItem != 0)
  1024.         { CheckItem(theMenu, inMenuItem, true); }
  1025.     else
  1026.         { CheckItem(theMenu, menuItemCount, true); }
  1027.                 
  1028.     // 3. find where to place the menu
  1029.     Point where;
  1030.     where.v = itemBounds.top;
  1031.     where.h = itemBounds.right;
  1032.     
  1033.     LocalToGlobal(&where);
  1034.     
  1035.     // 4. handle the menu click
  1036.     PlotPopupIcon(inDialogItem, ttSelected);
  1037.     
  1038.     InsertMenu(theMenu, -1);
  1039.     
  1040.     long thing = PopUpMenuSelect(theMenu, where.v, where.h, inMenuItem - 1);
  1041.     
  1042.     PlotPopupIcon(inDialogItem, ttNone);
  1043.     
  1044.     // 5. feed back the result
  1045.     short outMenuItem = thing & 0x0000FFFF;
  1046.     
  1047.     
  1048.     // 6. search for the item in our menu (same way we built it)
  1049.     result = false;
  1050.     
  1051.     menuItemCount = 0;
  1052.     
  1053.     firstKindFound = kUnsetIndex;
  1054.     for(kindIndex = 0; kindIndex < numKinds; kindIndex++)
  1055.     {            
  1056.         Boolean    seperatorAdded = false;
  1057.     
  1058.         for(needIndex = 0; needIndex < mNumNeeds; needIndex++)
  1059.         {
  1060.             if (mNeeds[needIndex].theKind == validKinds[kindIndex] &&
  1061.                 // only show appropriate labels unless option key is down (unless it was already selected)
  1062.                 (needIndex == inNeed || (keyModifiers & optionKey) || IsAppropriateNeed (mNeeds[needIndex], elementKind, elementLabel)) &&
  1063.                 // don't show needs with kISpNeedFlag_Utility bit set unless the option key is down (unless it was already selected)
  1064.                 (needIndex == inNeed || (keyModifiers & optionKey) || !(mNeeds[needIndex].flags & kISpNeedFlag_Utility)))
  1065.             {
  1066.                 if (!seperatorAdded)
  1067.                 {
  1068.                     if (firstKindFound == kUnsetIndex)
  1069.                         firstKindFound = kindIndex;
  1070.                     else if (firstKindFound != kindIndex)
  1071.                     {
  1072.                         menuItemCount++;
  1073.                         seperatorAdded = true;
  1074.                     }
  1075.                 }
  1076.                 
  1077.                 menuItemCount++;
  1078.                 
  1079.                 if (menuItemCount == outMenuItem)
  1080.                 {
  1081.                     outNeed = needIndex;
  1082.                     result = true;
  1083.                     break;
  1084.                 }
  1085.             }
  1086.         }
  1087.     }
  1088.     
  1089.     if (outMenuItem == menuItemCount + 2)
  1090.     {
  1091.         outNeed = kUnsetIndex;
  1092.         result = true;
  1093.     }
  1094.     
  1095.     DeleteMenu(kMenuID_TempMenu);
  1096.     DisposeMenu(theMenu);
  1097.  
  1098.     
  1099.     return result;
  1100. }
  1101.  
  1102.  
  1103. /* =============================================================================
  1104.  *        PlotPopupIcon (protected)
  1105.  *
  1106.  *    Draws the icon that represents the current state of the popup menu dialog
  1107.  *    user item, which is given by its actual position in the dialog items.
  1108.  * ========================================================================== */
  1109. void ISpPlugInUI::PlotPopupIcon(
  1110.     short                inItem,                                                // absolute item number
  1111.     IconTransformType    inTransform)                                        // transform
  1112. {
  1113.     UInt32 itemIndex = inItem - mBaseDITLCount;                                // index relative to our DITL
  1114.     UInt32 *dialogItemToNeedMapping = GetDialogItemToNeedMapping();            // 
  1115.     UInt32 thisItem = dialogItemToNeedMapping[itemIndex];
  1116.     OSStatus status;
  1117.         
  1118.     NAG_RETURN(((thisItem <= mNumNeeds) || (thisItem == kUnsetIndex)), "ISpPlugInUI::PlotPopupIcon item out of range");
  1119.     
  1120.     // get icon suite from needs or set it to the none icon suite 
  1121.     short iconSuiteID;
  1122.     if (thisItem != kUnsetIndex) { iconSuiteID = mNeeds[thisItem].iconSuiteResourceId; }
  1123.     else { iconSuiteID = kISpNoneIconSuite; }
  1124.  
  1125.     if (DialogItemIsInvisable (mDialog, inItem))        // if item is hidden, don't draw
  1126.         { return; }
  1127.     
  1128.     //handle hiliting the item if the element is active on the device
  1129.     if (IsPressed(inItem)) { inTransform |= kISpIconTransform_DeviceActive; }
  1130.     
  1131.     // set the port and draw the icon
  1132.     {
  1133.         GWorldState port_saver(mDialog);    // set port to mDialog and restore on exit
  1134.         
  1135.         // Find the item's rectangle
  1136.         Rect itemBounds;    
  1137.         DialogItem_GetRect(mDialog, inItem, &itemBounds);
  1138.         
  1139.         // Plot the Icon    
  1140.         status = ISpPlotAppIconSuite(&itemBounds, atCenterRight, inTransform | ttLabel3, iconSuiteID);
  1141.         WARNING(status == noErr, "ISpPlotAppIconSuite failed in PlotPopupIcon");
  1142.     }
  1143. }
  1144.  
  1145. void ISpPlugInUI::HandleStickClick (
  1146.         Point                where,
  1147.         short                dialogItem,
  1148.         UInt32                upDialogItem,
  1149.         UInt32                downDialogItem,
  1150.         UInt32                leftDialogItem,
  1151.         UInt32                rightDialogItem,
  1152.         UInt32                oldNeed,
  1153.         UInt32                &newNeed)
  1154. {
  1155.     UInt32 * dialogItemToNeedMapping = GetDialogItemToNeedMapping();
  1156.     
  1157.     UInt32 itemIndex = dialogItem - mBaseDITLCount;
  1158.  
  1159.     ISpElementLabel        elementLabel;
  1160.  
  1161.     if (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1162.         { elementLabel = kISpElementLabel_Axis_XAxis; }
  1163.     else
  1164.         { elementLabel = kISpElementLabel_Axis_YAxis; }
  1165.  
  1166.     if (CheckPopUpHit (where, dialogItem, kISpElementKind_Axis, elementLabel, validStickKinds, validStickKindsCount, oldNeed, newNeed) &&
  1167.         oldNeed != newNeed)
  1168.     {
  1169.         // clear old values (if necessary)
  1170.         if (oldNeed != kUnsetIndex) switch (mNeeds[oldNeed].theKind)
  1171.         {
  1172.             case kISpElementKind_Movement:
  1173.             case kISpElementKind_DPad:
  1174.                 dialogItemToNeedMapping[upDialogItem] = kUnsetIndex;
  1175.                 dialogItemToNeedMapping[downDialogItem] = kUnsetIndex;
  1176.                 dialogItemToNeedMapping[leftDialogItem] = kUnsetIndex;
  1177.                 dialogItemToNeedMapping[rightDialogItem] = kUnsetIndex;
  1178.                 break;
  1179.             
  1180.             case kISpElementKind_Axis:
  1181.                 if (itemIndex == upDialogItem || itemIndex == downDialogItem)
  1182.                 {
  1183.                     dialogItemToNeedMapping[upDialogItem] = kUnsetIndex;
  1184.                     dialogItemToNeedMapping[downDialogItem] = kUnsetIndex;
  1185.                 }
  1186.                 else // (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1187.                 {
  1188.                     dialogItemToNeedMapping[leftDialogItem] = kUnsetIndex;
  1189.                     dialogItemToNeedMapping[rightDialogItem] = kUnsetIndex;
  1190.                 }
  1191.                 break;
  1192.         }
  1193.         
  1194.         // set new values
  1195.         if (newNeed == kUnsetIndex)
  1196.         {
  1197.             dialogItemToNeedMapping[itemIndex] = newNeed;
  1198.         }
  1199.         else switch (mNeeds[newNeed].theKind)
  1200.         {
  1201.             case kISpElementKind_Movement:
  1202.             case kISpElementKind_DPad:
  1203.                 dialogItemToNeedMapping[upDialogItem] = newNeed;
  1204.                 dialogItemToNeedMapping[downDialogItem] = newNeed;
  1205.                 dialogItemToNeedMapping[leftDialogItem] = newNeed;
  1206.                 dialogItemToNeedMapping[rightDialogItem] = newNeed;
  1207.                 break;
  1208.             
  1209.             case kISpElementKind_Axis:
  1210.                 if (itemIndex == upDialogItem || itemIndex == downDialogItem)
  1211.                 {
  1212.                     dialogItemToNeedMapping[upDialogItem] = newNeed;
  1213.                     dialogItemToNeedMapping[downDialogItem] = newNeed;
  1214.                 }
  1215.                 else // (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1216.                 {
  1217.                     dialogItemToNeedMapping[leftDialogItem] = newNeed;
  1218.                     dialogItemToNeedMapping[rightDialogItem] = newNeed;
  1219.                 }
  1220.                 break;
  1221.             
  1222.             case kISpElementKind_Button:
  1223.                 dialogItemToNeedMapping[itemIndex] = newNeed;
  1224.                 break;
  1225.             
  1226.         }
  1227.         
  1228.         mDirty = true;
  1229.         SetVirtualElements ();
  1230.  
  1231.         PlotPopupIcon(upDialogItem + mBaseDITLCount, ttNone);
  1232.         PlotPopupIcon(downDialogItem + mBaseDITLCount, ttNone);
  1233.         PlotPopupIcon(leftDialogItem + mBaseDITLCount, ttNone);
  1234.         PlotPopupIcon(rightDialogItem + mBaseDITLCount, ttNone);
  1235.     }
  1236. }
  1237.  
  1238. void ISpPlugInUI::HandleMouseClick (
  1239.         Point                where,
  1240.         short                dialogItem,
  1241.         UInt32                upDialogItem,
  1242.         UInt32                downDialogItem,
  1243.         UInt32                leftDialogItem,
  1244.         UInt32                rightDialogItem,
  1245.         UInt32                oldNeed,
  1246.         UInt32                &newNeed)
  1247. {
  1248.     UInt32 * dialogItemToNeedMapping = GetDialogItemToNeedMapping();
  1249.     
  1250.     UInt32 itemIndex = dialogItem - mBaseDITLCount;
  1251.  
  1252.     ISpElementLabel        elementLabel;
  1253.  
  1254.     if (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1255.         { elementLabel = kISpElementLabel_Delta_X; }
  1256.     else
  1257.         { elementLabel = kISpElementLabel_Delta_Y; }
  1258.  
  1259.     if (CheckPopUpHit (where, dialogItem, kISpElementKind_Delta, elementLabel, validMouseKinds, validMouseKindsCount, oldNeed, newNeed) &&
  1260.         oldNeed != newNeed)
  1261.     {
  1262.         // clear old values (if necessary)
  1263.         if (oldNeed != kUnsetIndex) switch (mNeeds[oldNeed].theKind)
  1264.         {
  1265.             case kISpElementKind_Movement:
  1266.             case kISpElementKind_DPad:
  1267.                 dialogItemToNeedMapping[upDialogItem] = kUnsetIndex;
  1268.                 dialogItemToNeedMapping[downDialogItem] = kUnsetIndex;
  1269.                 dialogItemToNeedMapping[leftDialogItem] = kUnsetIndex;
  1270.                 dialogItemToNeedMapping[rightDialogItem] = kUnsetIndex;
  1271.                 break;
  1272.             
  1273.             case kISpElementKind_Delta:
  1274.             case kISpElementKind_Axis:
  1275.                 if (itemIndex == upDialogItem || itemIndex == downDialogItem)
  1276.                 {
  1277.                     dialogItemToNeedMapping[upDialogItem] = kUnsetIndex;
  1278.                     dialogItemToNeedMapping[downDialogItem] = kUnsetIndex;
  1279.                 }
  1280.                 else // (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1281.                 {
  1282.                     dialogItemToNeedMapping[leftDialogItem] = kUnsetIndex;
  1283.                     dialogItemToNeedMapping[rightDialogItem] = kUnsetIndex;
  1284.                 }
  1285.                 break;
  1286.         }
  1287.         
  1288.         // set new values
  1289.         if (newNeed == kUnsetIndex)
  1290.         {
  1291.             dialogItemToNeedMapping[itemIndex] = newNeed;
  1292.         }
  1293.         else switch (mNeeds[newNeed].theKind)
  1294.         {
  1295.             case kISpElementKind_Movement:
  1296.             case kISpElementKind_DPad:
  1297.                 dialogItemToNeedMapping[upDialogItem] = newNeed;
  1298.                 dialogItemToNeedMapping[downDialogItem] = newNeed;
  1299.                 dialogItemToNeedMapping[leftDialogItem] = newNeed;
  1300.                 dialogItemToNeedMapping[rightDialogItem] = newNeed;
  1301.                 break;
  1302.             
  1303.             case kISpElementKind_Delta:
  1304.             case kISpElementKind_Axis:
  1305.                 if (itemIndex == upDialogItem || itemIndex == downDialogItem)
  1306.                 {
  1307.                     dialogItemToNeedMapping[upDialogItem] = newNeed;
  1308.                     dialogItemToNeedMapping[downDialogItem] = newNeed;
  1309.                 }
  1310.                 else // (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1311.                 {
  1312.                     dialogItemToNeedMapping[leftDialogItem] = newNeed;
  1313.                     dialogItemToNeedMapping[rightDialogItem] = newNeed;
  1314.                 }
  1315.                 break;
  1316.             
  1317.             case kISpElementKind_Button:
  1318.                 dialogItemToNeedMapping[itemIndex] = newNeed;
  1319.                 break;
  1320.             
  1321.         }
  1322.         
  1323.         mDirty = true;
  1324.         SetVirtualElements ();
  1325.  
  1326.         PlotPopupIcon(upDialogItem + mBaseDITLCount, ttNone);
  1327.         PlotPopupIcon(downDialogItem + mBaseDITLCount, ttNone);
  1328.         PlotPopupIcon(leftDialogItem + mBaseDITLCount, ttNone);
  1329.         PlotPopupIcon(rightDialogItem + mBaseDITLCount, ttNone);
  1330.     }
  1331. }
  1332.  
  1333.  
  1334. void ISpPlugInUI::HandleDeltaClick (
  1335.         Point                where,
  1336.         short                dialogItem,
  1337.         ISpElementLabel        elementLabel,
  1338.         UInt32                minDeltaDialogItem,
  1339.         UInt32                maxDeltaDialogItem,
  1340.         UInt32                oldNeed,
  1341.         UInt32                &newNeed)
  1342. {
  1343.     UInt32 * dialogItemToNeedMapping = GetDialogItemToNeedMapping();
  1344.     
  1345.     UInt32 itemIndex = dialogItem - mBaseDITLCount;
  1346.  
  1347.     if (CheckPopUpHit (where, dialogItem, kISpElementKind_Delta, elementLabel, validDeltaKinds, validDeltaKindsCount, oldNeed, newNeed) &&
  1348.         oldNeed != newNeed)
  1349.     {
  1350.         // clear old values (if necessary)
  1351.         if (oldNeed != kUnsetIndex) switch (mNeeds[oldNeed].theKind)
  1352.         {
  1353.             case kISpElementKind_Delta:
  1354.             case kISpElementKind_Axis:
  1355.                 dialogItemToNeedMapping[minDeltaDialogItem] = kUnsetIndex;
  1356.                 dialogItemToNeedMapping[maxDeltaDialogItem] = kUnsetIndex;
  1357.                 break;
  1358.         }
  1359.         
  1360.         // set new values
  1361.         if (newNeed == kUnsetIndex)
  1362.         {
  1363.             dialogItemToNeedMapping[itemIndex] = newNeed;
  1364.         }
  1365.         else switch (mNeeds[newNeed].theKind)
  1366.         {
  1367.             case kISpElementKind_Delta:
  1368.             case kISpElementKind_Axis:
  1369.                 dialogItemToNeedMapping[minDeltaDialogItem] = newNeed;
  1370.                 dialogItemToNeedMapping[maxDeltaDialogItem] = newNeed;
  1371.                 break;
  1372.             
  1373.             case kISpElementKind_Button:
  1374.                 dialogItemToNeedMapping[itemIndex] = newNeed;
  1375.                 break;
  1376.             
  1377.         }
  1378.         
  1379.         mDirty = true;
  1380.         SetVirtualElements ();
  1381.  
  1382.         PlotPopupIcon(minDeltaDialogItem + mBaseDITLCount, ttNone);
  1383.         PlotPopupIcon(maxDeltaDialogItem + mBaseDITLCount, ttNone);
  1384.     }
  1385. }
  1386.  
  1387.  
  1388. void ISpPlugInUI::HandleAxisClick (
  1389.     Point                        where,
  1390.     short                        itemNo,
  1391.     ISpElementLabel                elementLabel,
  1392.     UInt32                        minAxisDialogItem,
  1393.     UInt32                        maxAxisDialogItem,
  1394.     UInt32                        oldNeed,
  1395.     UInt32                        &newNeed)
  1396. {
  1397.     UInt32 * dialogItemToNeedMapping = GetDialogItemToNeedMapping();
  1398.  
  1399.     UInt32 itemIndex = itemNo - mBaseDITLCount;
  1400.     
  1401.     if (CheckPopUpHit (where, itemNo, kISpElementKind_Axis, elementLabel, validAxisKinds, validAxisKindsCount, oldNeed, newNeed) &&
  1402.         oldNeed != newNeed)
  1403.     {
  1404.         // clear old values (if necessary)
  1405.         if (oldNeed != kUnsetIndex) switch (mNeeds[oldNeed].theKind)
  1406.         {
  1407.             case kISpElementKind_Axis:
  1408.                 dialogItemToNeedMapping[minAxisDialogItem] = kUnsetIndex;
  1409.                 dialogItemToNeedMapping[maxAxisDialogItem] = kUnsetIndex;
  1410.                 break;
  1411.         }
  1412.         
  1413.         // set new values
  1414.         if (newNeed == kUnsetIndex)
  1415.         {
  1416.             dialogItemToNeedMapping[itemIndex] = newNeed;
  1417.         }
  1418.         else switch (mNeeds[newNeed].theKind)
  1419.         {
  1420.             case kISpElementKind_Axis:
  1421.                 dialogItemToNeedMapping[minAxisDialogItem] = newNeed;
  1422.                 dialogItemToNeedMapping[maxAxisDialogItem] = newNeed;
  1423.                 break;
  1424.             
  1425.             case kISpElementKind_Button:
  1426.                 dialogItemToNeedMapping[itemIndex] = newNeed;
  1427.                 break;
  1428.             
  1429.         }
  1430.         
  1431.         mDirty = true;
  1432.         SetVirtualElements ();
  1433.  
  1434.         PlotPopupIcon(minAxisDialogItem + mBaseDITLCount, ttNone);
  1435.         PlotPopupIcon(maxAxisDialogItem + mBaseDITLCount, ttNone);
  1436.     }
  1437. }
  1438.  
  1439. void ISpPlugInUI::HandlePedalAxisClick (
  1440.     Point                        where,
  1441.     short                        itemNo,
  1442.     ISpElementLabel                elementLabel,
  1443.     UInt32                        oldNeed,
  1444.     UInt32                        &newNeed)
  1445. {
  1446.     UInt32 * dialogItemToNeedMapping = GetDialogItemToNeedMapping();
  1447.  
  1448.     UInt32 itemIndex = itemNo - mBaseDITLCount;
  1449.     
  1450.     if (CheckPopUpHit (where, itemNo, kISpElementKind_Axis, elementLabel, validAxisKinds, validAxisKindsCount, oldNeed, newNeed) &&
  1451.         oldNeed != newNeed)
  1452.     {
  1453.         // set new value
  1454.         dialogItemToNeedMapping[itemIndex] = newNeed;
  1455.         
  1456.         mDirty = true;
  1457.         SetVirtualElements ();
  1458.  
  1459.         PlotPopupIcon(itemIndex + mBaseDITLCount, ttNone);
  1460.     }
  1461. }
  1462.  
  1463. void ISpPlugInUI::HandleButtonClick (
  1464.     Point                        where,
  1465.     short                        itemNo,
  1466.     ISpElementLabel                elementLabel,
  1467.     UInt32                        oldNeed,
  1468.     UInt32                        &newNeed)
  1469. {
  1470.     UInt32 * dialogItemToNeedMapping = GetDialogItemToNeedMapping();
  1471.  
  1472.     UInt32 itemIndex = itemNo - mBaseDITLCount;
  1473.     
  1474.     if (CheckPopUpHit (where, itemNo, kISpElementKind_Button, elementLabel, validButtonKinds, validButtonKindsCount, oldNeed, newNeed) &&
  1475.         oldNeed != newNeed)
  1476.     {
  1477.         // set new value
  1478.         dialogItemToNeedMapping[itemIndex] = newNeed;
  1479.         
  1480.         mDirty = true;
  1481.         SetVirtualElements ();
  1482.  
  1483.         PlotPopupIcon(itemIndex + mBaseDITLCount, ttNone);
  1484.     }
  1485. }
  1486.  
  1487. void ISpPlugInUI::HandleDPadClick (
  1488.     Point                        where,
  1489.     short                        itemNo,
  1490.     UInt32                        upDialogItem,
  1491.     UInt32                        downDialogItem,
  1492.     UInt32                        leftDialogItem,
  1493.     UInt32                        rightDialogItem,
  1494.     UInt32                        oldNeed,
  1495.     UInt32                        &newNeed)
  1496. {
  1497.     UInt32 * dialogItemToNeedMapping = GetDialogItemToNeedMapping();
  1498.  
  1499.     UInt32 itemIndex = itemNo - mBaseDITLCount;
  1500.     
  1501.     // susbsitute this label for the element label for popup 'hinting' (IsAppropriateLabel)
  1502.     ISpElementLabel elementLabel;
  1503.     
  1504.     if (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1505.         { elementLabel = kISpElementLabel_Axis_XAxis; }
  1506.     else
  1507.         { elementLabel = kISpElementLabel_Axis_YAxis; }
  1508.             
  1509.     if (CheckPopUpHit (where, itemNo, kISpElementKind_DPad, elementLabel, validPOVKinds, validPOVKindsCount, oldNeed, newNeed) &&
  1510.         oldNeed != newNeed)
  1511.     {
  1512.         // clear old values (if necessary)
  1513.         if (oldNeed != kUnsetIndex) switch (mNeeds[oldNeed].theKind)
  1514.         {
  1515.             case kISpElementKind_DPad:
  1516.             case kISpElementKind_Movement:
  1517.                 dialogItemToNeedMapping[upDialogItem] = kUnsetIndex;
  1518.                 dialogItemToNeedMapping[downDialogItem] = kUnsetIndex;
  1519.                 dialogItemToNeedMapping[leftDialogItem] = kUnsetIndex;
  1520.                 dialogItemToNeedMapping[rightDialogItem] = kUnsetIndex;
  1521.                 break;
  1522.             
  1523.             case kISpElementKind_Axis:
  1524.                 if (itemIndex == upDialogItem || itemIndex == downDialogItem)
  1525.                 {
  1526.                     dialogItemToNeedMapping[upDialogItem] = kUnsetIndex;
  1527.                     dialogItemToNeedMapping[downDialogItem] = kUnsetIndex;
  1528.                 }
  1529.                 else // (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1530.                 {
  1531.                     dialogItemToNeedMapping[leftDialogItem] = kUnsetIndex;
  1532.                     dialogItemToNeedMapping[rightDialogItem] = kUnsetIndex;
  1533.                 }
  1534.                 break;
  1535.         }
  1536.         
  1537.         // set new values
  1538.         if (newNeed == kUnsetIndex)
  1539.         {
  1540.             dialogItemToNeedMapping[itemIndex] = newNeed;
  1541.         }
  1542.         else switch (mNeeds[newNeed].theKind)
  1543.         {
  1544.             case kISpElementKind_DPad:
  1545.             case kISpElementKind_Movement:
  1546.                 dialogItemToNeedMapping[upDialogItem] = newNeed;
  1547.                 dialogItemToNeedMapping[downDialogItem] = newNeed;
  1548.                 dialogItemToNeedMapping[leftDialogItem] = newNeed;
  1549.                 dialogItemToNeedMapping[rightDialogItem] = newNeed;
  1550.                 break;
  1551.             
  1552.             case kISpElementKind_Axis:
  1553.                 if (itemIndex == upDialogItem || itemIndex == downDialogItem)
  1554.                 {
  1555.                     dialogItemToNeedMapping[upDialogItem] = newNeed;
  1556.                     dialogItemToNeedMapping[downDialogItem] = newNeed;
  1557.                 }
  1558.                 else // (itemIndex == leftDialogItem || itemIndex == rightDialogItem)
  1559.                 {
  1560.                     dialogItemToNeedMapping[leftDialogItem] = newNeed;
  1561.                     dialogItemToNeedMapping[rightDialogItem] = newNeed;
  1562.                 }
  1563.                 break;
  1564.             
  1565.             case kISpElementKind_Button:
  1566.                 dialogItemToNeedMapping[itemIndex] = newNeed;
  1567.                 break;
  1568.             
  1569.         }
  1570.         
  1571.         mDirty = true;
  1572.         SetVirtualElements ();
  1573.  
  1574.         PlotPopupIcon(upDialogItem + mBaseDITLCount, ttNone);
  1575.         PlotPopupIcon(downDialogItem + mBaseDITLCount, ttNone);
  1576.         PlotPopupIcon(leftDialogItem + mBaseDITLCount, ttNone);
  1577.         PlotPopupIcon(rightDialogItem + mBaseDITLCount, ttNone);
  1578.     }
  1579.  
  1580. }
  1581.  
  1582. void MakeDialogItemInvisable (DialogRef theDialog, short itemNo)
  1583. {
  1584.     WARNING(theDialog != nil,                "MakeDialogItemInvisable dlog == nil");
  1585.     WARNING(CountDITL(theDialog) >= itemNo,    "MakeDialogItemInvisable item >= CountDITL(dlog)");
  1586.     WARNING(itemNo > 0,                        "MakeDialogItemInvisable item <= 0");
  1587.  
  1588.     // Find the item's rectangle
  1589.     short itemType;
  1590.     Handle itemHandle;
  1591.     Rect itemBounds;
  1592.     
  1593.     GetDialogItem(theDialog, itemNo, &itemType, &itemHandle, &itemBounds);
  1594.     
  1595.     // make zero size rectangle
  1596.     itemBounds.bottom = itemBounds.top;
  1597.     itemBounds.right = itemBounds.left;
  1598.     
  1599.     SetDialogItem(theDialog, itemNo, itemType, itemHandle, &itemBounds);
  1600.     
  1601.     if (itemType & ctrlItem)
  1602.         HideControl((ControlHandle) itemHandle);
  1603. }
  1604.  
  1605. Boolean    DialogItemIsInvisable (DialogRef theDialog, short itemNo)
  1606. {
  1607.     WARNING(theDialog != nil,                "DialogItemIsInvisable dlog == nil");
  1608.     WARNING(CountDITL(theDialog) >= itemNo,    "DialogItemIsInvisable item >= CountDITL(dlog)");
  1609.     WARNING(itemNo > 0,                        "DialogItemIsInvisable item <= 0");
  1610.  
  1611.     Boolean isInvisable = false;
  1612.     
  1613.     // Find the item's rectangle
  1614.     short itemType;
  1615.     Handle itemHandle;
  1616.     Rect itemBounds;
  1617.     
  1618.     GetDialogItem(theDialog, itemNo, &itemType, &itemHandle, &itemBounds);
  1619.     
  1620.     if (itemBounds.bottom == itemBounds.top)
  1621.         isInvisable = true;
  1622.     else if (itemBounds.right == itemBounds.left)
  1623.         isInvisable = true;
  1624.     
  1625.     return isInvisable;
  1626. }
  1627.  
  1628. void SetDialogItemWidth (DialogRef theDialog, short itemNo, short width)
  1629. {
  1630.     WARNING(theDialog != nil,                "SetDialogItemWidth dlog == nil");
  1631.     WARNING(CountDITL(theDialog) >= itemNo,    "SetDialogItemWidth item >= CountDITL(dlog)");
  1632.     WARNING(itemNo > 0,                        "SetDialogItemWidth item <= 0");
  1633.  
  1634.     // Find the item's rectangle
  1635.     short itemType;
  1636.     Handle itemHandle;
  1637.     Rect itemBounds;
  1638.     
  1639.     GetDialogItem(theDialog, itemNo, &itemType, &itemHandle, &itemBounds);
  1640.     
  1641.     // change the width
  1642.     itemBounds.right = itemBounds.left + width;
  1643.     
  1644.     SetDialogItem(theDialog, itemNo, itemType, itemHandle, &itemBounds);
  1645. }
  1646.  
  1647. OSStatus CreateDeviceFromResource(    short resId, 
  1648.                                     UInt32 refCon,
  1649.                                     ISpDeviceReference &device)
  1650. {
  1651.     Handle h;
  1652.     OSStatus err;
  1653.     ISpDeviceDefinition def;
  1654.     
  1655.     // read the resource from the res file
  1656.     h = Get1Resource('isdv', resId);
  1657.     err = ResError();
  1658.  
  1659.     // debugging
  1660.     WARNING(h != nil,                             "CreateDeviceFromResource: Get1Resource failed (h == nil)");
  1661.     WARNING(err == noErr,                         "CreateDeviceFromResource: Get1Resource failed (err != noErr)");
  1662.     WARNING(GetHandleSize(h) == sizeof(def),     "CreateDeviceFromResource: Get1Resource failed (bad handle size)");
  1663.  
  1664.     // error checking
  1665.     if (h == nil) { err = -1; }
  1666.     if (err) { return err; }
  1667.  
  1668.     // copy the handle to a structure    and release the handle    
  1669.     BlockMoveData(*h, &def, sizeof(def));
  1670.     ReleaseResource(h);
  1671.  
  1672.     // input sprocket call to create the device
  1673.     err = ISpDevice_New(&def, (ISpDriverFunctionPtr_MetaHandler) ISpPlugInUI::MetaHandler, refCon, &device);
  1674.     
  1675.     return err;
  1676. }
  1677.  
  1678. OSStatus CreateElementFromResource(short elementResId, short configResID, ISpDeviceReference device, ISpElementReference &element)
  1679. {
  1680.     Handle h1;                        // handle to resource based element definition structure
  1681.     Handle h2;                        // handle to resource based element configuration info
  1682.     OSStatus err;        
  1683.     ISpElementDefinitionStruct def;    // actual element definition structure
  1684.     
  1685.     // read the element definition struct from a resource
  1686.     h1 = Get1Resource('isel', elementResId);
  1687.     err = ResError();
  1688.  
  1689.     // debugging
  1690.     WARNING(h1 != nil, "CreateElementFromResource: Get1Resource failed (h1 == nil)");
  1691.     WARNING(err == noErr, "CreateElementFromResource: Get1Resource failed (err != noErr)");
  1692.     WARNING(GetHandleSize(h1) == sizeof(def), "CreateElementFromResource: Get1Resource failed (bad handle size)");
  1693.  
  1694.     // error checking on element definition structure
  1695.     if (err) { return err; }
  1696.     if (h1 == nil) { return -1; }
  1697.     
  1698.     // read the configuration information from a resource
  1699.     h2 = Get1Resource('isei', configResID);
  1700.     err = ResError();
  1701.     
  1702.     // debugging
  1703.     WARNING(h2 != nil, "CreateElementFromResource: Get1Resource failed (h2 == nil)");
  1704.     WARNING(err == noErr, "CreateElementFromResource: Get1Resource failed (err != noErr)");
  1705.  
  1706.     // copy the element definition struct handle into the structure and fill in the config info
  1707.     BlockMoveData(*h1, &def, sizeof(def));
  1708.     if (h2) 
  1709.     {
  1710.         HLock(h2);
  1711.         def.configInfo = *h2;
  1712.         def.configInfoLength = GetHandleSize(h2); 
  1713.     }
  1714.         
  1715.     // set the device field
  1716.     def.device = device;
  1717.  
  1718.     // create the input sprocket device
  1719.     err = ISpElement_New(&def, &element);
  1720.  
  1721.     // release our handles
  1722.     HUnlock(h2);
  1723.     ReleaseResource(h1);
  1724.     ReleaseResource(h2);
  1725.     
  1726.     return err;
  1727. }
  1728.  
  1729. // ••• here and down are possible speed dependent functions
  1730. #pragma mark ------ fast functions ------
  1731. #if __MWERKS__
  1732. #pragma optimize_for_size reset
  1733. #endif
  1734.  
  1735.  
  1736. void AxisToButtons(UInt32 axis, UInt32 buttons[2])
  1737. {
  1738.     if (axis > 0xafffffff)
  1739.         { buttons[0] = kISpButtonUp; buttons[1] = kISpButtonDown; }
  1740.     else if (axis < 0x4fffffff)
  1741.         { buttons[0] = kISpButtonDown; buttons[1] = kISpButtonUp; }
  1742.     else
  1743.         { buttons[0] = kISpButtonUp; buttons[1] = kISpButtonUp; }
  1744. }
  1745.  
  1746. void PedalAxisToButton(UInt32 axis, UInt32 & button)
  1747. {
  1748.     if (axis > 0x4fffffff)
  1749.         button = kISpButtonDown;
  1750.     else
  1751.         button = kISpButtonUp;
  1752. }
  1753.  
  1754. UInt32 AxisToDPad(UInt32 xAxis, UInt32 yAxis)
  1755. {
  1756.     UInt32 hat;
  1757.  
  1758.     if (yAxis < 0x4fffffff)
  1759.         {
  1760.             if (xAxis < 0x4fffffff)
  1761.                 { hat = kISpPadDownLeft; }
  1762.             else if (xAxis > 0xafffffff)
  1763.                 { hat = kISpPadDownRight; }
  1764.             else
  1765.                 { hat = kISpPadDown; }
  1766.         }
  1767.     else if (yAxis > 0xafffffff)
  1768.         {
  1769.             if (xAxis < 0x4fffffff)
  1770.                 { hat = kISpPadUpLeft; }
  1771.             else if (xAxis > 0xafffffff)
  1772.                 { hat = kISpPadUpRight; }
  1773.             else
  1774.                 { hat = kISpPadUp; }
  1775.         }
  1776.     else
  1777.         {
  1778.             if (xAxis < 0x4fffffff)
  1779.                 { hat = kISpPadLeft; }
  1780.             else if (xAxis > 0xafffffff)
  1781.                 { hat = kISpPadRight; }
  1782.             else
  1783.                 { hat = kISpPadIdle; }
  1784.         }
  1785.  
  1786.     return hat;
  1787. }
  1788.  
  1789. UInt32 BooleanDirectionsToDPad(UInt32 up, UInt32 left, UInt32 down, UInt32 right)
  1790. {
  1791.     SInt8 x = 0;
  1792.     SInt8 y = 0;
  1793.     
  1794.     if (left) x--;
  1795.     if (right) x++;
  1796.     
  1797.     if (up) y++;
  1798.     if (down) y--;
  1799.     
  1800.     return DigitalAxisToDPad (x, y);
  1801. }
  1802.  
  1803. UInt32 DigitalAxisToDPad(SInt8 x, SInt8 y)
  1804. {
  1805.     UInt32    result = kISpPadIdle;
  1806.     
  1807.     switch (x)
  1808.     {
  1809.         case -1:
  1810.             switch(y)
  1811.             {    
  1812.                 case 1:        result = kISpPadUpLeft;        break;
  1813.                 case 0:        result = kISpPadLeft;        break;
  1814.                 case -1:    result = kISpPadDownLeft;    break;
  1815.             }
  1816.             break;
  1817.         case 0:
  1818.             switch(y)
  1819.             {
  1820.                 case 1:        result = kISpPadUp;            break;
  1821.                 case 0:        result = kISpPadIdle;        break;
  1822.                 case -1:    result = kISpPadDown;        break;
  1823.             }
  1824.             break;
  1825.         case 1:
  1826.             switch(y)
  1827.             {
  1828.                 case 1:        result = kISpPadUpRight;    break;
  1829.                 case 0:        result = kISpPadRight;        break;
  1830.                 case -1:    result = kISpPadDownRight;    break;
  1831.             }
  1832.             break;
  1833.     }
  1834.     
  1835.     return result;
  1836. }
  1837.  
  1838. void DPadToButtonsAndAxis(UInt32 dpad, UInt32 buttons[4], UInt32 axis[2])
  1839. {
  1840.     switch(dpad)
  1841.     {
  1842.         case kISpPadIdle:
  1843.             buttons[0] = kISpButtonUp;
  1844.             buttons[1] = kISpButtonUp;
  1845.             buttons[2] = kISpButtonUp;
  1846.             buttons[3] = kISpButtonUp;
  1847.             
  1848.             axis[0] = kISpAxisMiddle;
  1849.             axis[1] = kISpAxisMiddle;                
  1850.         break;
  1851.         
  1852.         case kISpPadLeft:
  1853.             buttons[0] = kISpButtonUp;
  1854.             buttons[1] = kISpButtonDown;
  1855.             buttons[2] = kISpButtonUp;
  1856.             buttons[3] = kISpButtonUp;
  1857.             
  1858.             axis[0] = kISpAxisMinimum;
  1859.             axis[1] = kISpAxisMiddle;                
  1860.         break;
  1861.     
  1862.         case kISpPadUpLeft:
  1863.             buttons[0] = kISpButtonDown;
  1864.             buttons[1] = kISpButtonDown;
  1865.             buttons[2] = kISpButtonUp;
  1866.             buttons[3] = kISpButtonUp;
  1867.             
  1868.             axis[0] = kISpAxisMinimum;
  1869.             axis[1] = kISpAxisMaximum;                
  1870.         break;
  1871.         
  1872.         case kISpPadUp:
  1873.             buttons[0] = kISpButtonDown;
  1874.             buttons[1] = kISpButtonUp;
  1875.             buttons[2] = kISpButtonUp;
  1876.             buttons[3] = kISpButtonUp;
  1877.             
  1878.             axis[0] = kISpAxisMiddle;
  1879.             axis[1] = kISpAxisMaximum;                
  1880.         break;
  1881.         
  1882.         case kISpPadUpRight:
  1883.             buttons[0] = kISpButtonDown;
  1884.             buttons[1] = kISpButtonUp;
  1885.             buttons[2] = kISpButtonUp;
  1886.             buttons[3] = kISpButtonDown;
  1887.             
  1888.             axis[0] = kISpAxisMaximum;
  1889.             axis[1] = kISpAxisMaximum;                
  1890.         break;
  1891.         
  1892.         case kISpPadRight:
  1893.             buttons[0] = kISpButtonUp;
  1894.             buttons[1] = kISpButtonUp;
  1895.             buttons[2] = kISpButtonUp;
  1896.             buttons[3] = kISpButtonDown;
  1897.             
  1898.             axis[0] = kISpAxisMaximum;
  1899.             axis[1] = kISpAxisMiddle;                
  1900.         break;
  1901.         
  1902.         case kISpPadDownRight:
  1903.             buttons[0] = kISpButtonUp;
  1904.             buttons[1] = kISpButtonUp;
  1905.             buttons[2] = kISpButtonDown;
  1906.             buttons[3] = kISpButtonDown;
  1907.             
  1908.             axis[0] = kISpAxisMaximum;
  1909.             axis[1] = kISpAxisMinimum;                
  1910.         break;
  1911.         
  1912.         case kISpPadDown:
  1913.             buttons[0] = kISpButtonUp;
  1914.             buttons[1] = kISpButtonUp;
  1915.             buttons[2] = kISpButtonDown;
  1916.             buttons[3] = kISpButtonUp;
  1917.             
  1918.             axis[0] = kISpAxisMiddle;
  1919.             axis[1] = kISpAxisMinimum;                
  1920.         break;
  1921.  
  1922.         case kISpPadDownLeft:
  1923.             buttons[0] = kISpButtonUp;
  1924.             buttons[1] = kISpButtonDown;
  1925.             buttons[2] = kISpButtonDown;
  1926.             buttons[3] = kISpButtonUp;
  1927.             
  1928.             axis[0] = kISpAxisMinimum;
  1929.             axis[1] = kISpAxisMinimum;                
  1930.         break;
  1931.     }
  1932. }
  1933.  
  1934. UInt32 DPadReverseVertical(UInt32 dpad)
  1935. {
  1936.     UInt32 result = 0;
  1937.     
  1938.     switch (dpad)
  1939.     {
  1940.         case kISpPadLeft:
  1941.         case kISpPadIdle:
  1942.         case kISpPadRight:
  1943.             result = dpad;
  1944.             break;
  1945.     
  1946.         case kISpPadUpLeft:
  1947.             result = kISpPadDownLeft;                
  1948.             break;
  1949.         
  1950.         case kISpPadUp:
  1951.             result = kISpPadDown;                
  1952.             break;
  1953.         
  1954.         case kISpPadUpRight:
  1955.             result = kISpPadDownRight;                
  1956.             break;
  1957.         
  1958.         case kISpPadDownLeft:
  1959.             result = kISpPadUpLeft;                
  1960.             break;
  1961.         
  1962.         case kISpPadDown:
  1963.             result = kISpPadUp;                
  1964.             break;
  1965.  
  1966.         case kISpPadDownRight:
  1967.             result = kISpPadUpRight;                
  1968.             break;
  1969.     }
  1970.     
  1971.     return result;
  1972. }
  1973.  
  1974.